package org.opens.netty.chatServer.client.handle;

import com.google.gson.*;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import io.netty.util.concurrent.Promise;
import lombok.extern.slf4j.Slf4j;
import org.opens.netty.chatServer.message.RpcRequestMessage;
import org.opens.netty.chatServer.message.RpcResponseMessage;

import java.lang.reflect.Type;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 当前handle有多个线程访问的资源PROMISE_MAP, 但是我们考虑了线程安全问题, 所以仍旧是可以共享的
 */
@Slf4j
@ChannelHandler.Sharable
public class RpcResponseMessageHandle extends SimpleChannelInboundHandler<RpcResponseMessage> {

    /**
     * 该数据多个线程会访问它, 所以选用ConcurrentHashMap
     * 注意:
     * - 这里不能设置为Map<Integer, Promise<?>>, 因为泛型通配符只能读取值, 而不能设置值
     */
    public static final Map<Integer, Promise<Object>> PROMISE_MAP = new ConcurrentHashMap<>();

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcResponseMessage msg) throws Exception {
        log.info("client收到: {}", msg);
        int sequenceId = msg.getSequenceId();
        // 获取并移除
        Promise<Object> promise = PROMISE_MAP.remove(sequenceId);
        if (promise != null) {
            // 调用成功就放入成功的结果, 调用失败就放入异常的结果
            if (msg.getExceptionValue() == null) {
                promise.setSuccess(msg.getReturnValue());
            } else {
                promise.setFailure(msg.getExceptionValue());
            }
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {

    }

}
